#include "filter.h"
#include "utils.h"

namespace sdms
{
//and操作符，取两个集合的共有部分
//调用前应该已经执行了对应的SQL操作
//若假定docid是排序过的，可以进行算法的优化？
Filter operator&&(const Filter& lf,const Filter& rf)
{
    Filter f;
    for(int i=0; i<lf.docid.size(); i++)
    {
        for(int j=0; j<rf.docid.size(); j++)
        {
            if (lf.docid[i]==rf.docid[j]) f.docid.push_back(lf.docid[i]);
        }
    }
    return f;
}
//or操作符，取两个集合的和
Filter operator||(const Filter& lf,const Filter& rf)
{
    Filter f;
    f.docid=rf.docid;
    for(int i=0; i<lf.docid.size(); i++)
    {
        bool has_same=false;
        for(int j=0; j<rf.docid.size(); j++)
        {
            if (lf.docid[i]==rf.docid[j])
            {
                has_same=true;
                break;
            }
        }
        if (!has_same) f.docid.push_back(lf.docid[i]);
    }
    return f;
}
Filter& Filter::operator=(const Filter& rf)
{
    docid=rf.docid;
    doc=rf.doc;
    sql=rf.sql;
    return *this;
}
bool Filter::operator==(const Filter& lf)
{
    return (sql==lf.sql);
}
string Filter::tostring() const
{
    string r;
    for(int i=0; i<docid.size(); i++)
    {
        if(i==0) r="(";
        r+=utils::toString(docid[i]);
        if(i==docid.size()-1) r+=")";
        else r+=",";
    }
    return r;
}
unsigned int Filter::get_id() const
{
    return id;
}
string Filter::get_sql() const
{
    return sql;
}

void Filter::set_id(const unsigned int i)
{
    id=i;
}
void Filter::set_name(const string& n)
{
    name=n;
}
string Filter::get_name() const
{
    return name;
}
bool Filter::empty()
{
    return docid.empty();
}
void Filter::clear()
{
    docid.clear();
}
void WritingFilter::eval()
{
    sql="select distinct writingItems.itemID as id from writingItems ";
    if (id) sql+=" where writingID="+utils::toString(id);
    else sql+=" ,writing where writing.id=writingItems.writingID and writing.name like '%"+name+"%'";
    docid=doc->getfilter(sql);
}
void categoryfilter::eval()
{
    sql="select distinct doc_id from cat_doc ";
    if (id) sql+=" where cat_id="+utils::toString(id);
    else sql+=" ,category where cat_doc.cat_id=category.id and category.name like '%"+name+"%'";
    docid=doc->getfilter(sql);
}
void PublisherFilter::eval()
{
    sql="select distinct itemData.itemID from itemData left join itemDataValues on itemData.valueID=itemDataValues.valueID where  ( itemData.fieldID=12 or itemData.fieldID=8)";
    if (name!="") sql+=" and itemDataValues.value='"+utils::escapeSQL(name)+"'";
    //std::cout<<sql<<std::endl;
    docid=doc->getfilter(sql);
}
void AbstractFilter::eval()
{
    sql="select distinct itemData.itemID from itemData left join itemDataValues on itemData.valueID=itemDataValues.valueID where  ( itemData.fieldID=90)";
    if (name!="") sql+=" and itemDataValues.value like '%"+utils::escapeSQL(name)+"%'";
    //std::cout<<sql<<std::endl;
    docid=doc->getfilter(sql);
}

void TagFilter::eval()
{
    sql="select distinct itemTags.itemID from itemTags";
    if (id) sql+=" where tagID="+utils::toString(id);
    else sql+=" ,tags where tags.tagID=itemTags.tagID and tags.name like '%"+name+"%'";
    docid=doc->getfilter(sql);
}
void DocumentFilter::eval()
{
    sql="SELECT items.itemID as id FROM items left join itemTypes on items.itemTypeID=itemTypes.itemTypeID LEFT JOIN itemData ON items.itemID = itemData.itemID LEFT JOIN itemDataValues ON itemData.valueID = itemDataValues.valueID WHERE itemData.fieldID=110 and itemTypes.itemTypeID<>14  ";
    //if (id) sql+=" where tag_id="+utils::toString(id);
    //else
    sql+=" and itemDataValues.value like '%"+name+"%'";
    docid=doc->getfilter(sql);
}
void NoPublisherFilter::eval()
{
    sql="select distinct itemID from items where itemTypeID<>14 and itemID not in (select distinct itemData.itemID from itemData left join itemDataValues on itemData.valueID=itemDataValues.valueID where  ( itemData.fieldID=12 or itemData.fieldID=8) and itemDataValues.value is not null)";
    docid=doc->getfilter(sql);
    name="No Publisher";
}
void NotReading::eval()
{
    sql="select distinct id from document where id not in (select doc_id from theme_doc)";
    docid=doc->getfilter(sql);
    name="Not themed";
}
void NoTagFilter::eval()
{
    sql="select distinct itemID from items where itemTypeID<>14 and itemID not in (select distinct itemID from itemTags)";
    docid=doc->getfilter(sql);
    name="No tag";
}
void ReadingFilter::eval()
{
    sql="select distinct itemID from reading ";
    //if (id) sql+=" where id="+utils::toString(id);
    switch(id)
    {
    case 1://expired
        sql+="where date(dateSchedual)<date('now') and dateFinished=''";
        name="reading expired";
        break;
    case 2://10 days
        sql+="where date(dateSchedual)>=date('now') and date(dateSchedual)<date('now','+10 day') and dateFinished=''";
        name="10 days reading";
        break;
    case 3://future
        sql+="where date(dateSchedual)>=date('now','+10 day') and dateFinished=''";
        name="future reading";
        break;
    case 4://history
        sql+="where dateFinished<>''";
        name="history reading";
        break;
    case 5://selected date
        sql+="where date(dateSchedual)=date('"+name+"')";
        break;
    default:
        break;
    }
    docid=doc->getfilter(sql);
}
};
